//
// WebSocketServer.cpp
//
// $Id: //poco/1.4/Net/samples/WebSocketServer/src/WebSocketServer.cpp#1 $
//
// This sample demonstrates the WebSocket class.
//
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//

#include <Poco/AutoPtr.h>
#include <Poco/Net/HTTPServer.h>
#include <Poco/Net/HTTPRequestHandler.h>
#include <Poco/Net/HTTPServerParams.h>
#include <Poco/Net/HTTPServerRequest.h>
#include <Poco/Net/HTTPServerResponse.h>
#include <Poco/Net/HTTPServerParams.h>
#include <Poco/Net/ServerSocket.h>
#include <Poco/Util/ServerApplication.h>
#include <Poco/Util/Option.h>
#include <Poco/Util/OptionSet.h>
#include <Poco/Util/HelpFormatter.h>
#include <Poco/Format.h>
#include <Poco/FileChannel.h>
#include <Poco/DateTimeFormatter.h>
#include <Poco/PatternFormatter.h>
#include <Poco/FormattingChannel.h>
#include <iostream>

using namespace Poco;
using namespace Poco::Net;
using namespace Poco::Util;

#include "WebRequestHandlerFactory.h"
#include "MainApplication.h"

Logger *pLogger = nullptr;

int MainApplication::main(const std::vector<std::string>& args)
{
	initLogger(std::string(this->commandName() + ".log"));

    // get parameters from configuration file
    unsigned short port = (unsigned short) config().getInt("WebSocketServer.port", 9998);

    // set-up a server socket
    ServerSocket svs(port);
    // set-up a HTTPServer instance
    HTTPServer srv(new WebRequestHandlerFactory, svs, new HTTPServerParams);
    // start the HTTPServer
    srv.start();
    // wait for CTRL-C or kill
    waitForTerminationRequest();
    // Stop the HTTPServer
    srv.stop();

    return Application::EXIT_OK;
}

void MainApplication::initialize(Application& self)
{
	Application::initialize(self);
	//std::cout << commandName() << std::endl;
}

void MainApplication::uninitialize()
{
	Application::uninitialize();
	//std::cout << __func__ << "is called..." << std::endl;
}

void MainApplication::defineOptions(OptionSet& options)
{
	Application::defineOptions( options );
	//logger().information(std::string(__func__) + " is called");

	options.addOption(Option("help", "h", "Display help information on command line arguments.")
			.required(false)
			.repeatable(false)
			.callback(OptionCallback<MainApplication>(this, &MainApplication::handleHelp))
			);
}

void MainApplication::handleHelp(const std::string& name, const std::string& value)
{
	HelpFormatter helpFormatter( options() );
    helpFormatter.setCommand(commandName());
    helpFormatter.setUsage("OPTIONS");
    helpFormatter.setHeader("websocket server usage");
    helpFormatter.format(std::cout);

	exit(0);
}

void MainApplication::initLogger(const std::string& strLogName)
{
	AutoPtr<FileChannel> pChannel(new FileChannel);
	pChannel->setProperty("path", strLogName);
	pChannel->setProperty("rotation", "2 M");
	pChannel->setProperty("archive", "timestamp");

	AutoPtr<PatternFormatter> pPF(new PatternFormatter);
	pPF->setProperty("pattern", "%Y-%m-%d %H:%M:%S %s: %t");
	pPF->setProperty("times","local");
	AutoPtr<FormattingChannel> pFC(new FormattingChannel(pPF, pChannel));
	logger().setChannel(pFC);

	pLogger = &logger();
}


POCO_SERVER_MAIN(MainApplication)
